package com.study.cloud.gateway.core.config;

import com.study.cloud.gateway.common.util.PropertiesUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;

/**
 * @author wangwancheng
 * @create 2025/7/18 14:31
 */
@Slf4j
public class ConfigLoader {

    //配置环境
    private static final String CONFIG_FILE = "gateway.properties";
    //环境变量
    private static final String ENV_PREFIX = "GATEWAY_";
    //jvm参数
    private static final String JVM_PREFIX = "gateway.";


    //单例模式
    // 静态内部类，持有外部类的实例
    private static class LazingHolder {
        private static final ConfigLoader INSTANCE = new ConfigLoader();
    }

    // 提供全局访问点
    public static ConfigLoader getInstance() {
        return LazingHolder.INSTANCE;
    }

    private Config config;

    public static Config getConfig() {
        return getInstance().config;
    }

    /**
     * 优先级高的覆盖优先级低的
     * 运行参数 > jvm参数 > 环境变量 > 配置文件 > 默认值
     * @param args
     * @return
     */
    public Config load(String args[]) {
        //默认值
        config = new Config();
        //配置文件
        loadFromConfigFile();
        //环境变量
        loadFromEnv();
        //jvm参数
        loadFromJvm();
        //运行参数
        loadFromArgs(args);
        return config;
    }

    private void loadFromConfigFile() {
       InputStream inputStream = ConfigLoader.class.getClassLoader().getResourceAsStream(CONFIG_FILE);
       if (inputStream != null){
           Properties properties = new Properties();
           try {
               properties.load(inputStream);
               PropertiesUtils.properties2Object(properties,config);
           } catch (IOException e) {
               log.warn("load config file {} error",CONFIG_FILE);
           }finally {
               try {
                   if (inputStream != null){
                       inputStream.close();
                   }
               } catch (IOException e) {
                   log.warn("close input stream error");
               }
           }
       }
    }

    private void loadFromEnv() {
        Map<String,String> env = System.getenv();
        Properties  properties = new Properties();
        properties.putAll(env);
        PropertiesUtils.properties2Object(properties,config,ENV_PREFIX);
    }

    private void loadFromJvm() {
        Properties  properties = System.getProperties();
        PropertiesUtils.properties2Object(properties,config,JVM_PREFIX);
    }

    private void loadFromArgs(String[] args) {
        if (args != null && args.length > 0){
            Properties  properties = new Properties();
            for (String arg : args) {
                if (arg.startsWith("--") && arg.contains("=")){
                    properties.put(arg.substring(2,arg.indexOf("=")),
                            arg.substring(arg.indexOf("=")+1));
                }
            }
            PropertiesUtils.properties2Object(properties,config);
        }


    }
}
